﻿using CoachingOrganizer.Logic.Helpers;
using CoachingOrganizer.Logic.Logic.Tools.EmotionsPack;
using CoachingOrganizer.Toolkit.Events;
using CoachingOrganizer.Toolkit.Threading.CollectionsDecorators;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CoachingOrganizer.Logic.Models.Tools.EmotionsPack
{
    public class EmotionsPackModel : ToolModelBase
    {
        private readonly EmotionsTraceModel _emotionsTrace = new EmotionsTraceModel();
        private readonly SimpleCollectionLoadDecorator<EmotionTraceModel> _emotions;
        private EmotionTraceModel _selectedEmotion;

        public EmotionsTraceModel EmotionsTrace
        {
            get { return _emotionsTrace; }
        }

        public EmotionTraceModel SelectedEmotion
        {
            get { return _selectedEmotion; }
            set
            {
                _selectedEmotion = value;
                OnSelectedEmotionChanged();
            }
        }

        public event EventHandler SelectedEmotionChanged;

        public event NotifyCollectionChangedEventHandler EmotionTraceItemsCollectionChanged;

        internal Func<ActionResult<IEnumerable<EmotionTraceItemLogic>>> EnumerateTraceItemsDelegate;

        internal Func<string, ActionResult<EmotionTraceLogic>> RequestEmotionTraceDelegate;

        public EmotionsPackModel()
        {
            _emotions = new SimpleCollectionLoadDecorator<EmotionTraceModel>(EnumerateEmotions);

        }

        public async Task LoadTraceItemsAsync(System.Threading.CancellationToken cancelLoad)
        {
            await Task.Run(() => _emotions.FillItemsList());
            IEnumerable<EmotionTraceModel> traceModels = _emotions.Items;
            if (traceModels != null)
                foreach (EmotionTraceModel traceModel in traceModels)
                    await traceModel.LoadTraceItemsAsync(cancelLoad);
        }

        public IEnumerable<EmotionTraceItemModel> EnumerateEmotionTraceItems()
        {
            IEnumerable<EmotionTraceModel> traceModels = _emotions.Items;
            return traceModels == null ? null : traceModels.SelectMany(e => e.TraceItems);
        }

        public void SetSelectedEmotionByName(string emotionName)
        {
            ActionResult<EmotionTraceLogic> requestResult = RequestEmotionTraceDelegate(emotionName);
            if (requestResult.IsValid)
                _selectedEmotion = requestResult.Result.Model;
        }

        internal void NotifyEmotionTraceItemsCollectionChanged(NotifyCollectionChangedEventArgs args)
        {
            OnEmotionTraceItemsCollectionChanged(args);
        }

        internal void ModifyEmotionCollection(Action<IList<EmotionTraceModel>> modificationDelegate)
        {
            _emotions.ModifyCollection(modificationDelegate);
        }

        private ActionResult<IEnumerable<EmotionTraceModel>> EnumerateEmotions()
        {
            return ActionResult<IEnumerable<EmotionTraceModel>>.GetValidResult(new EmotionTraceModel[0]);
        }

        protected virtual void OnSelectedEmotionChanged()
        {
            EventHandler handler = SelectedEmotionChanged;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        protected virtual void OnEmotionTraceItemsCollectionChanged(NotifyCollectionChangedEventArgs args)
        {
            NotifyCollectionChangedEventHandler handler = EmotionTraceItemsCollectionChanged;
            if (handler != null)
                handler(this, args);
        }
    }
}
